React Native基础之调用Android本地方法

前言

学习了一周React native之后,感觉还挺有意思的,今天来说说通过React native调用Android平台的一些本地方法(API),以我目前的水平,感觉这个功能可能平时用的不会太多,但我感觉通过React native开发Android应用的过程中肯定会有用到的时候,本文以调用Android平台的Toast为例来讲讲如何通过React native调用Android
原生的一些方法(API)。

下面开始项目从创建到运行成功的全过程

创建项目

1
react-native init CallNativeToast

创建一个NativeModule

本地模块一般是继承ReactContextBaseJavaModule的Java类,然后实现React native(js)调用Android本地API所需的功能,我们这次目标是通过js调用Android来展示一个Toast,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ToastModule extends ReactContextBaseJavaModule {
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "ToastExample";
}
@Nullable
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
return constants;
}
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
}

有几点需要说明:

  • getName返回的NativeModule名字,在后面JaveScript代码中是用来表示此类的,在js中我们可以通过NativeModule.ToastExample来访问此类

  • 为了能够在js中调用Android的本地方法,需要被调用的方法必须加上@ReactMethod注释,作为js和java中的桥梁方法,该方法返回类型需要是void,访问权限为public

  • getConstants函数可实现,可不实现,主要是返回一些暴露给js的常量值,用于一些预定义的常量值,在js到java过程中的同步和一致。

注册模块

接着就是在自定义的Package中注册上一步创建的NativeModule,如果不注册,上一步创建的NativeModule对于js是不可用的,也就是说如果想要在js中使用自己创建的NativeModule,必须要注册,注册是在createNativeModules方法中完成的,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ToastReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ToastModule(reactContext));
return modules;
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

注册之后你需要在MainApplication(init创建项目的时候自动会生成此类)类中的getPackage方法中添加自定义的Package类的实例,代码如下:

1
2
3
4
5
6
7
@Override
protected List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new ToastReactPackage()
);
}

到此,在Java层(Android本地)的工作算是完成了,接着就是如何在js中调用了

JS中调用

为了方便其他模块以后共用,或者说是为了项目结构清晰,我们把创建的NativeModule模块单独包装到一个js文件中,作为一个简单的库供其他文件引用,命名为ToastAndroid.js,代码如下:

1
2
3
4
5
'use strict';

import { NativeModules } from 'react-native';

module.exports = NativeModules.ToastExample;

那么我们就可以在另一个js文件中引入上面的文件,来调用上面的文件中所定义的展示toast的方法了,命名为TestToast.js,部分代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React, { Component } from 'react'
import {
StyleSheet,
View,
Button,
PixelRatio
} from 'react-native';

import ToastExample from './ToastAndroid'

export default class ToastTest extends Component {
render() {
return (
<View style={styles.container}>
<Button style={styles.big_button}
title="点击调用Android原生Toast"
onPress={this.onButtonClick}
accessibilityLabel="展示一个Toast信息" />
</View>
);
}

onButtonClick(event) {
ToastExample.show('Hello,原生Toast!', ToastExample.SHORT)
}
}

上面就是一个简单的React native布局,一个按钮,点击的时候调用ToastExample模块中定义的show方法

最后为了能够展示该界面,我们在index.android.js中引用上述js文件并注册到项目,部分代码如下:

1
2
3
4
5
6
7
import React from 'react'
import {
AppRegistry,
} from 'react-native';
import ToastTest from './TestToast'

AppRegistry.registerComponent('CallNativeToast', () => ToastTest)

运行截图

是时候放一张运行成功的图了

结尾

React Native调用Android本地方法(API)到这就算是成功了,github完整代码:请戳这里